package hu.rsc.feeds.client.data;

import hu.rsc.feeds.client.gui.table2.ImmutableIterator;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.google.gwt.user.client.rpc.IsSerializable;

/**
 * An ordered list of filter info where each entry tells us how to filter a single column.
 */
public class ColumnFilterList implements IsSerializable {
    /**
     * A List used to manage the insertion/removal of {@link ColumnFilterInfo}.
     */
    private List<ColumnFilterInfo> infos = new ArrayList<ColumnFilterInfo>();

    /**
     * Add a {@link ColumnFilterInfo} to this list. If the column already exists, it will be removed from its current
     * position and placed at the start of the list, becoming the primary sort info.
     * 
     * This add method inserts an entry at the beginning of the list. It does not append the entry to the end of the
     * list.
     * 
     * @param column
     *            the column index
     * @param filter
     *            is the filter
     */
    public void add(ColumnFilterInfo info) {
	// Remove sort info for duplicate columns
	for (int i = 0; i < this.infos.size(); i++) {
	    ColumnFilterInfo curInfo = this.infos.get(i);
	    if (curInfo.getColumn() == info.getColumn()) {
		this.infos.remove(i);
		i--;
	    }
	}

	// Insert the new sort info
	if (info.getFilter() != null) {
	    this.infos.add(0, info);
	}
    }

    /**
     * Check if this object is equal to another.
     * 
     * @param csl
     *            the other object
     * @return true if objects are equal
     */
    public boolean equals(ColumnFilterList cfl) {
	// Object is null
	if (cfl == null) {
	    return false;
	}

	// Check the size of the lists
	int size = this.size();
	if (size != cfl.size()) {
	    return false;
	}

	// Compare the entries
	for (int i = 0; i < size; i++) {
	    if (!this.infos.get(i).equals(cfl.infos.get(i))) {
		return false;
	    }
	}

	// Everything is equal
	return true;
    }

    @Override
    public boolean equals(Object obj) {
	if (obj instanceof ColumnFilterList) {
	    return this.equals((ColumnFilterList) obj);
	}
	return false;
    }

    @Override
    public int hashCode() {
	return super.hashCode();
    }

    public Iterator<ColumnFilterInfo> iterator() {
	return new ImmutableIterator<ColumnFilterInfo>(this.infos.iterator());
    }

    /**
     * Returns the number of {@link ColumnFilterInfo} in the list.
     * 
     * @return the size of the list
     */
    public int size() {
	return this.infos.size();
    }

}
